package logic

import (
	"context"
	"github.com/golang-jwt/jwt/v4"
	"go-exp/common/redis"
	"go-exp/pkg/ctxdata"
	"go-exp/pkg/json"
	"go-exp/pkg/myjwt"
	"go-exp/zero/rpc/user/pb/user"
	"google.golang.org/grpc/metadata"
	"strconv"
	"time"

	"go-exp/zero/rpc/oauth/internal/svc"
	"go-exp/zero/rpc/oauth/pb/oauth"

	"github.com/zeromicro/go-zero/core/logx"
)

type OauthLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewOauthLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OauthLogic {
	return &OauthLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

// 验证
func (l *OauthLogic) Oauth(in *oauth.OauthReq) (*oauth.AuthResp, error) {
	// todo: add your logic here and delete this line
	l.ctx = metadata.AppendToOutgoingContext(l.ctx, "userId", "transport userId by matedata")
	remoteUser, err := l.svcCtx.UserRpc.GetUserByUsername(l.ctx, &user.GetUserByUsernameRequest{Username: in.Username})
	if err != nil {
		return nil, err
	}
	if remoteUser.Id == 0 {
		return nil, err
	}
	now := time.Now().Unix()
	payloadMap := &ctxdata.AuthClaims{
		UserID:   remoteUser.Id,
		UserName: remoteUser.Username,
		Role:     "userRole",
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Unix(l.svcCtx.Config.AuthConf.AccessExpire+now, 0)), // 过期时间
			IssuedAt:  jwt.NewNumericDate(time.Unix(now, 0)),                                       // 签发时间
			NotBefore: jwt.NewNumericDate(time.Unix(now, 0)),                                       // 生效时间
			Issuer:    "system",                                                                    // 签发者
			Subject:   "go-exp",                                                                    // 主题
		},
	}
	token, err := myjwt.GenToken(l.svcCtx.Config.AuthConf.AccessSecret, *payloadMap)
	if err != nil {
		return nil, err
	}
	remoteUserJson, _ := json.Unmarshal(remoteUser)
	l.svcCtx.Redis.Client.Set(l.ctx, redis.AuthKey+strconv.FormatInt(remoteUser.Id, 10), remoteUserJson, time.Second*3600)
	logx.Infof("remoteUser: %v", remoteUser)
	return &oauth.AuthResp{
		AccessToken: token,
	}, err
}
